package com.client.rel.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.client.rel.ReleaseClient;
import com.client.rel.data.ExecShellFailData;
import com.client.rel.enums.PrjInfoContainer;
import com.client.rel.model.ExecShell;
import com.client.rel.utils.ClientUtil;
import com.system.comm.utils.FrameFileUtil;
import com.system.handle.model.ResponseCode;
import com.system.handle.model.ResponseFrame;

/**
 * service接口
 * @author yuejing
 * @date 2016年1月29日 下午9:31:59
 * @version V1.0.0
 */
@RestController
public class ProjectController {

    private final Logger LOGGER = LoggerFactory.getLogger(ProjectController.class);
    
	/**
	 * 根据服务ID获取服务列表的信息
	 * @param serviceId
	 * @return
	 */
	@RequestMapping(value = "/project/release")
	public ResponseFrame serviceList(Integer prjId, Integer container, String shellScript,
			String pathUrl, String version, String healthCheckUrl,
			Integer isFirstDeploy) {
		try {
			ResponseFrame frame = new ResponseFrame();
			/*
			FrameMapUtil.getString(map, "code"),
			FrameMapUtil.getString(map, "name")*/
			//发布项目
			ReleaseClient client = new ReleaseClient();
			client.release(prjId, version, container, shellScript, pathUrl, healthCheckUrl, isFirstDeploy);
			
			frame.setCode(ResponseCode.SUCC.getCode());
			return frame;
		} catch (Exception e) {
			LOGGER.error("处理业务异常: " + e.getMessage(), e);
			return new ResponseFrame(ResponseCode.SERVER_ERROR);
		}
	}

	/**
	 * 根据项目ID和指定的日志路劲获取日志信息
	 * @return
	 */
	@RequestMapping(value = "/project/log")
	public ResponseFrame log(Integer prjId, String logPath, Integer readLine) {
		try {
			ResponseFrame frame = new ResponseFrame();
			if(readLine == null) {
				readLine = 50;
			}
			List<String> logs = FrameFileUtil.readLastNLine(logPath, readLine);
			/*
			FrameMapUtil.getString(map, "code"),
			FrameMapUtil.getString(map, "name")*/
			frame.setBody(logs);
			frame.setCode(ResponseCode.SUCC.getCode());
			return frame;
		} catch (Exception e) {
			LOGGER.error("处理业务异常: " + e.getMessage(), e);
			return new ResponseFrame(ResponseCode.SERVER_ERROR);
		}
	}
	/**
	 * 根据项目ID和指定的日志路劲下载日志信息
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/project/downloadLog")
	public void downloadLog(HttpServletRequest request, HttpServletResponse response,
			Integer prjId, String logPath) throws IOException {
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;

		String downLoadPath = logPath;
		//String downLoadPath = ctxPath;

		long fileLength = new File(downLoadPath).length();
		int separator = downLoadPath.lastIndexOf(File.separator);
		if(separator == -1) {
			separator = downLoadPath.lastIndexOf("/");
		}
		response.setHeader("Content-disposition", "attachment; filename=" + downLoadPath.substring(separator + 1));
		response.setHeader("Content-Length", String.valueOf(fileLength));

		bis = new BufferedInputStream(new FileInputStream(downLoadPath));
		bos = new BufferedOutputStream(response.getOutputStream());
		byte[] buff = new byte[2048];
		int bytesRead;
		while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
			bos.write(buff, 0, bytesRead);
		}
		bis.close();
		bos.close();
	}

	/**
	 * 根据服务ID执行命令
	 * @param serviceId
	 * @return
	 */
	@RequestMapping(value = "/project/execShell")
	public ResponseFrame execShell(Integer prjId, String prjName, Integer container,
			String version, String shellScript, String type) {
		try {
			ResponseFrame frame = new ResponseFrame();
			String path = ClientUtil.getPrjPath(prjId, version);
			//执行命令
			PrjInfoContainer piContainer = PrjInfoContainer.get(container);
			if("linux".equals(piContainer.getSysType())) {
				execLinux(path, type, shellScript, prjId, prjName, version, piContainer);
			} else if("win".equals(piContainer.getSysType())) {
				execWin(path, type, shellScript, prjId, prjName, version, piContainer);
			}
			frame.setCode(ResponseCode.SUCC.getCode());
			return frame;
		} catch (Exception e) {
			LOGGER.error("处理业务异常: " + e.getMessage(), e);
			return new ResponseFrame(ResponseCode.SERVER_ERROR);
		}
	}
	
	public void execWin(String path, String type, String shellScript, Integer prjId, String prjName, String version, PrjInfoContainer piContainer) throws Exception {
		//生成可执行的bat文件
		String batName = version + "_" + type + ".bat";
		File shFile = FrameFileUtil.readFile(path + batName);
		ExecShellFailData.add(new ExecShell(batName, version, path, piContainer));

		String command = ClientUtil.convertCommand(shellScript, prjId, prjName, version);
		FrameFileUtil.writeFile(command, shFile);

		/*String[] cmdChmod = {"/bin/sh", "-c", "chmod a+x " + path + shellName};
	Runtime.getRuntime().exec(cmdChmod).waitFor();*/
		String[] cmdChmod = {"cmd", "/c", "start " + path + batName};
		Runtime.getRuntime().exec(cmdChmod).waitFor();
		LOGGER.info("执行命令返回结果: 成功");
	}

	private void execLinux(String path, String type, String shellScript, Integer prjId, String prjName, String version, PrjInfoContainer piContainer) throws Exception {
		//生成可执行的shell文件
		String shellName = version + "_" + type + ".sh";
		File shFile = FrameFileUtil.readFile(path + shellName);
		ExecShellFailData.add(new ExecShell(shellName, version, path, piContainer));

		String command = ClientUtil.convertCommand(shellScript, prjId, prjName, version);
		FrameFileUtil.writeFile(command, shFile);

		/*String[] cmdChmod = {"/bin/sh", "-c", "chmod a+x " + path + shellName};
	Runtime.getRuntime().exec(cmdChmod).waitFor();*/

		String[] cmdChmod = {"/bin/sh", "-c", "chmod a+x " + path + shellName};
		Runtime.getRuntime().exec(cmdChmod).waitFor();

		//ProcessBuilder pb = new ProcessBuilder("." + path + shellName, param1, param2, param3);
		ProcessBuilder pb = new ProcessBuilder("./" + shellName);
		//设置要运行脚本的目录
		pb.directory(new File(path));
		int runningStatus = 0;
		Process p = pb.start();
		try {
			runningStatus = p.waitFor();
		} catch (InterruptedException e) {
		}
		BufferedReader br = new BufferedReader(new InputStreamReader(
				p.getInputStream()));
		StringBuffer sb = new StringBuffer();
		String line;
		int i=0;
		while ((line = br.readLine()) != null) {
			sb.append("["+(i++)+"]"+line).append("\n");
		}
		LOGGER.info("执行命令返回结果: {} - 运行状态: {}", sb.toString(), runningStatus);
		//runningStatus：运行状态，0标识正常。
	}
}